package src;

public class Multilevel {
	
	public Process [][] schedule = new Process[4][1000];
	public int timer = 0;
	public int [] runtime = {1,2,4,8};
	public Process [] addedpro = new Process[4000];
	
	public Multilevel(){
		
		this.run();
		
	}
	
	public void add(Process p){
		
		int j = 0;
		while(addedpro[j] != null){j++;}
		addedpro[j] = p;
		int i = 0;
		while(schedule[0][i] != null){i++;}
		schedule[0][i] = p;
		
	}
	
	public void run(){
		
		User u1 = new User("user1",1);
		User u2 = new User("user1",2);
		User u3 = new User("user1",3);
		Process [] pro = {
				new Process("process 1", 0, 3, u1),
				new Process("process 2", 1, 5, u1),
				new Process("process 3", 3, 2, u2),
				new Process("process 4", 7, 2, u3),
				new Process("process 5", 10,5, u2)
				};
		
		int totalruntime = totalrun(pro);
		boolean flag; //set to true if the current process has finished.
		
		while(timer < totalruntime){
			
			flag = false;
			
			for(int i = 0;i<pro.length;i++)
				if(pro[i].arrival <= timer && !added(pro[i]))
					this.add(pro[i]);
			
			for(int i = 0; i<schedule.length; i++){ //to find the highest non-empty priority level.
				
				if(schedule[i][0] == null)
					continue;
				for(int j = 0; j<runtime[i]; j++){
					
					if(schedule[i][0].remainingtime == 1){
						schedule[i][0].remainingtime--;
						schedule[i][0].run(timer);
						timer++;
						System.out.println("Process " + schedule[i][0].name + " has finished.");
						shiftup(i);
						flag = true;
						break;
					}
					schedule[i][0].remainingtime--;
					schedule[i][0].run(timer);
					timer++;
					
				}
				if(flag)
					break;
				
				if(i<3){
				int f = 0;
				while(schedule[i+1][f] != null){f++;}
				schedule[i+1][f] = schedule[i][0];
				shiftup(i);
				}else{
					
					int f = 0;
					while(schedule[i][f] != null){f++;}
					schedule[i][f] = schedule[i][0];
					shiftup(i);
					
				}
				break;
				
			}
			
		}
		
	}
	
	public boolean added(Process p) {
		
		for(int i = 0; i<addedpro.length && addedpro[i] != null; i++)
			if(addedpro[i].name.equalsIgnoreCase(p.name))
					return(true);
		return (false);
		
	}

	public int totalrun(Process[] p) {
		
		int totruntime = 0;
		for(int i = 0; i<p.length; i++)
			totruntime += p[i].runtime;
		return(totruntime);
		
	}

	public boolean done(){
		
		boolean flag = true;
		for(int i = 0; i<schedule.length; i++)
			if(schedule[i][0] != null)
				flag = false;
		return (flag);
		
	}
	
	public void shiftup(int col){
		
		for(int i=0; i<schedule[col].length && schedule[col][i] != null; i++)
			schedule[col][i] = schedule[col][i+1];
		
	}
	
}
